with v8.Generic_Handles;
package v8.Class_Handle_Scope is
   type Handle_Scope is tagged limited private;
   -- A stack-allocated class that governs a number of local handles.
   -- After a handle scope has been created, all local handles will be
   -- allocated within that handle scope until either the handle scope is
   -- deleted or another handle scope is created.  If there is already a
   -- handle scope and a new one is created, all allocations will take
   -- place in the new handle scope until it is deleted.  After that,
   -- new handles will again be allocated in the original handle scope.
   --
   -- After the handle scope of a local handle has been deleted the
   -- garbage collector will no longer track the object stored in the
   -- handle and may deallocate it.  The behavior of accessing a handle
   -- for which the handle scope has been deleted is undefined.

   function Number_Of_Handles return int;
   -- Counts the number of allocated handles.

   generic
      type Pointer is private;
      with package Handles is new v8.Generic_Handles (Pointer);
   function Close
     (this  : access Handle_Scope;
      value : Handles.Handle
     ) return Handles.Local;
   -- Closes the handle scope and returns the value as a handle in the
   -- previous scope, which is the new current scope after the call.
   --
   -- This routine is useful in c++, but not in ada.
   -- In c++, we can directly call handleScope.Close(h);
   -- but in ada, we must first make an instance of Close
   -- [TODO} how to make it more friendly in ada ?
   -- maybe move it into Class_Handle is more helpful

private


   package Cxx_HandleScope is
      type HandleScope is limited record
         Isolate    : System.Address; -- internal::Isolate--
         Prev_Next  : System.Address; -- internal::Object----
         Prev_Limit : System.Address; -- internal::Object----
         Is_Closed  : aliased bool;
      end record;
      pragma Import (CPP, HandleScope);

      function Create return HandleScope;
      pragma CPP_Constructor (Create, "_ZN2v811HandleScopeC1Ev");

      procedure Destroy (This : in out HandleScope);
      pragma Import (CPP, Destroy, "_ZN2v811HandleScopeD1Ev");

   end Cxx_HandleScope;
   pragma Import (CPP, Number_Of_Handles, "_ZN2v811HandleScope15NumberOfHandlesEv");

   type Handle_Scope is
     new Ada.Finalization.Limited_Controlled
   with record
      Internal : Cxx_HandleScope.HandleScope;
   end record;
   overriding procedure Finalize (This : in out Handle_Scope);
end v8.Class_Handle_Scope;
